package com.softWang.system.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.softWang.common.base.BaseServiceMy;
import com.softWang.common.exception.LogicException;
import com.softWang.system.mapper.SystemRoleDeptMapper;
import com.softWang.system.mapper.SystemRoleMenuMapper;
import com.softWang.system.mapper.SystemRolesMapper;
import com.softWang.system.mapper.SystemUserRoleMapper;
import com.softWang.system.controller.vo.systemRoles.ConvertSystemRoleMapper;
import com.softWang.system.controller.vo.systemRoles.SystemRoleGetRoleListResult;
import com.softWang.system.controller.vo.systemRoles.SystemRoleQueryAllParam;
import com.softWang.system.controller.vo.systemRoles.SystemRoleQueryAllResult;
import com.softWang.system.po.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class SystemRolesService extends BaseServiceMy<SystemRoles> {
    @Resource
    private SystemRolesMapper systemRolesMapper;
    @Resource
    private SystemRoleMenuMapper systemRoleMenuMapper;
    @Resource
    private SystemUserRoleMapper systemUserRoleMapper;

    @Resource
    private SystemRoleDeptMapper systemRoleDeptMapper;

    /**
     * 分页条件查询
     * @param param
     * @return
     */
    public List<SystemRoleQueryAllResult> queryall(SystemRoleQueryAllParam param){
        param.startPage();
        List<SystemRoleQueryAllResult> results=systemRolesMapper.queryall(param);
        return results;
    }

    /**
     * 插入角色
     * @param role 角色信息
     * @return 角色id
     */
    @Transactional
    public Long add(SystemRoles role) {
        // 验证参数信息
        valdation(role);
        // 设置参数信息
        role.setType(SystemRoles.Type.CREATED.getCode());
        role.setState(SystemRoles.State.NORMAL.getCode());

        systemRolesMapper.insert(role);

        //插入角色菜单关系
        List<Long> menuIds = role.getMenuIds();
        if(menuIds!= null && menuIds.size() > 0){
            List<SystemRoleMenu> roleMenus = new ArrayList<>();
            for(Long menuId : menuIds){
                SystemRoleMenu roleMenu = new SystemRoleMenu();
                roleMenu.setRoleid(role.getId());
                roleMenu.setMenuid(menuId);
                roleMenu.setHalf(0);
                roleMenus.add(roleMenu);
            }
            systemRoleMenuMapper.insert(roleMenus);
        }
        List<Long> halfMenuIds = role.getHalfMenuIds();
        if(halfMenuIds!= null && halfMenuIds.size() > 0){
            List<SystemRoleMenu> roleMenus = new ArrayList<>();
            for(Long menuId : halfMenuIds){
                SystemRoleMenu roleMenu = new SystemRoleMenu();
                roleMenu.setRoleid(role.getId());
                roleMenu.setMenuid(menuId);
                roleMenu.setHalf(1);
                roleMenus.add(roleMenu);
            }
            systemRoleMenuMapper.insert(roleMenus);
        }

        //插入数据权限部门表
        List<Long> deptIds = role.getDeptIds();
        if(deptIds!= null && deptIds.size() > 0){
            List<SystemRoleDept> roleDepts = new ArrayList<>();
            for(Long deptId : deptIds){
                SystemRoleDept roleDept = new SystemRoleDept();
                roleDept.setRoleid(role.getId());
                roleDept.setDeptId(deptId);
                roleDepts.add(roleDept);
            }
            systemRoleDeptMapper.insert(roleDepts);
        }
        return role.getId();
    }


    /**
     * 修改角色
     * @param role 角色信息
     * @return
     */
    @Transactional
    public Long edit(SystemRoles role) {
        // 验证参数信息
        valdation(role);

        systemRolesMapper.updateById(role);

        //删除角色菜单关系
        systemRoleMenuMapper.delete(new LambdaQueryWrapper<SystemRoleMenu>()
               .eq(SystemRoleMenu::getRoleid, role.getId()));
        //插入角色菜单关系
        List<Long> menuIds = role.getMenuIds();
        if(menuIds!= null && menuIds.size() > 0){
            List<SystemRoleMenu> roleMenus = new ArrayList<>();
            for(Long menuId : menuIds){
                SystemRoleMenu roleMenu = new SystemRoleMenu();
                roleMenu.setRoleid(role.getId());
                roleMenu.setMenuid(menuId);
                roleMenu.setHalf(0);
                roleMenus.add(roleMenu);
            }
            systemRoleMenuMapper.insert(roleMenus);
        }
        List<Long> halfMenuIds = role.getHalfMenuIds();
        if(halfMenuIds!= null && halfMenuIds.size() > 0){
            List<SystemRoleMenu> roleMenus = new ArrayList<>();
            for(Long menuId : halfMenuIds){
                SystemRoleMenu roleMenu = new SystemRoleMenu();
                roleMenu.setRoleid(role.getId());
                roleMenu.setMenuid(menuId);
                roleMenu.setHalf(1);
                roleMenus.add(roleMenu);
            }
            systemRoleMenuMapper.insert(roleMenus);
        }

        //删除数据权限部门表
        systemRoleDeptMapper.delete(new LambdaQueryWrapper<SystemRoleDept>()
                .eq(SystemRoleDept::getRoleid, role.getId()));
        //插入数据权限部门表
        List<Long> deptIds = role.getDeptIds();
        if(deptIds!= null && deptIds.size() > 0){
            List<SystemRoleDept> roleDepts = new ArrayList<>();
            for(Long deptId : deptIds){
                SystemRoleDept roleDept = new SystemRoleDept();
                roleDept.setRoleid(role.getId());
                roleDept.setDeptId(deptId);
                roleDepts.add(roleDept);
            }
            systemRoleDeptMapper.insert(roleDepts);
        }
        return role.getId();
    }

    /**
     * 获取详情
     * @param id id
     * @return
     */
    public SystemRoles getById(Long id) {
        return systemRolesMapper.selectById(id);
    }

    /**
     * 删除角色
     * @param ids id列表
     * @return void
     */
    @Transactional
    public void del(List<Long> ids) {
        //删除角色
        systemRolesMapper.deleteBatchIds(ids);
        //删除用户角色关系
        systemUserRoleMapper.delete(Wrappers.lambdaQuery(SystemUserRole.class)
                .in(SystemUserRole::getRoleid, ids));

        //删除角色菜单关系
        systemRoleMenuMapper.delete(new LambdaQueryWrapper<SystemRoleMenu>()
               .in(SystemRoleMenu::getRoleid, ids));
    }

    public List<Long> getMenuIdsByRoleId(Long roleId) {
        List<SystemRoleMenu> roleMenus = systemRoleMenuMapper.selectList(Wrappers.lambdaQuery(SystemRoleMenu.class)
                .eq(SystemRoleMenu::getRoleid, roleId)
                .eq(SystemRoleMenu::getHalf, 0));
        List<Long> menuIds = new ArrayList<>();
        for(SystemRoleMenu roleMenu : roleMenus){
            menuIds.add(roleMenu.getMenuid());
        }
        return menuIds;
    }


    private void valdation(SystemRoles param){
        // 验证名称唯一性
        Long num = systemRolesMapper.selectCount(
                new LambdaQueryWrapper<SystemRoles>()
                        .eq(SystemRoles::getRname, param.getRname())
                        .ne(param.getId()!=null,SystemRoles::getId, param.getId()));
        if (num > 0) {
            throw new LogicException("名称已存在!");
        }
        // 验证后台权限唯一性
        if(param.getCode()!=null && !"".equals(param.getCode().trim())) {
            Long keyNum = systemRolesMapper.selectCount(
                    new LambdaQueryWrapper<SystemRoles>()
                            .eq(SystemRoles::getCode, param.getCode())
                            .ne(param.getId() != null, SystemRoles::getId, param.getId()));
            if (keyNum > 0) {
                throw new LogicException("后台权限标识已存在!");
            }
        }
    }

    public List<SystemRoleGetRoleListResult> getRoleList() {
        List<SystemRoles> roles = systemRolesMapper.selectList(Wrappers.<SystemRoles>lambdaQuery(SystemRoles.class)
               .eq(SystemRoles::getState, SystemRoles.State.NORMAL.getCode()));
        List<SystemRoleGetRoleListResult> result = ConvertSystemRoleMapper.INSTANCE.toGetRoleListResults(roles);
        return result;
    }

    public List<Long> getDeptIdsByRoleId(Long roleId) {
        List<SystemRoleDept> reoleDepts = systemRoleDeptMapper.selectList(Wrappers.lambdaQuery(SystemRoleDept.class)
                .eq(SystemRoleDept::getRoleid, roleId));
        List<Long> deptIds = new ArrayList<>();
        for(SystemRoleDept releDept : reoleDepts){
            deptIds.add(releDept.getDeptId());
        }
        return deptIds;
    }
}
